package gis.toolkit;

import bean.common.Cell;
import bean.ltecover.Building;
import bean.ltecover.BuildingEx;
import com.sun.xml.bind.v2.util.CollisionCheckStack;
import gis.algorithm.*;
import gis.algorithm.voronoi.*;
import gis.algtest.BizBts;
import gis.algtest.BizService;
import gis.common.BuildingUtils;
import gis.common.GisConfig;
import gis.core.bean.KeyValue;
import gis.core.exception.LogicalException;
import gis.core.utils.*;
import gis.toolkit.Bean.GaodeResult;
import gis.toolkit.Bean.RegionRing;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.math.util.MathUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.URLEncoder;
import java.util.*;

/**
 * Created by Xiaobing on 2016/10/26.
 */
public class GaodoHelper {
    private String basePath = this.getClass().getResource("/").getPath();
    //private String basePath = GisConfig.GetInstance().getBasePath();
    private static Logger logger = LoggerFactory.getLogger(GaodoHelper.class);
    //http://ditu.amap.com/service/poiTipslite?&city=500000&words=舒馨园
    //http://ditu.amap.com/service/poiInfo?query_type=IDQ&pagesize=20&pagenum=1&qii=true&cluster_state=5&need_utd=true&utd_sceneid=1000&div=PC1000&addr_poi_merge=true&is_classify=true&id=B0017875A4&city=500105&keywords=光宇阳光地中海
    //http://ditu.amap.com/service/poiInfo?query_type=TQUERY&pagesize=20&pagenum=1&qii=true&cluster_state=5&need_utd=true&utd_sceneid=1000&div=PC1000&addr_poi_merge=true&is_classify=true&city=500000&rf=0&keywords=%E8%9E%8D%E7%A7%91
    String queryWord = "http://ditu.amap.com/service/poiTipslite";
    String queryCell = "http://ditu.amap.com/service/poiInfo?query_type=IDQ&pagesize=20&pagenum=1&qii=true&cluster_state=5&need_utd=true&utd_sceneid=1000&div=PC1000&addr_poi_merge=true&is_classify=true";
    String query = "http://ditu.amap.com/service/poiInfo?query_type=TQUERY&pagesize=20&qii=true&cluster_state=5&need_utd=true&utd_sceneid=1000&div=PC1000&addr_poi_merge=true&is_classify=true&city=210105&rf=0";//辽宁 210105  重庆：500000
    //String query = "http://ditu.amap.com/service/poiInfo?query_type=TQUERY&pagesize=20&pagenum=1&qii=true&cluster_state=5&need_utd=true&utd_sceneid=1000&div=PC1000&addr_poi_merge=true&is_classify=true&city=500000&rf=0&keywords=%E4%B8%96%E7%BA%AA%E6%96%B0%E5%9F%8E";
    String queryDetailById = "http://ditu.amap.com/detail/get/detail?id=";

    /**
     * @param args
     */
    public static void main(String[] args) {
        GaodoHelper helper = new GaodoHelper ();
        //helper.getData();
        //helper.getDataRegion();
        //helper.getPointChange();
        //helper.readZhudiwangxiaoqu();
        //helper.readGaodeComm();
        //helper.wZhudiwangxiaoqu();
        //helper.jiCell();f

        //11858139.6038,3433489.21699
        //106.52232140972,29.620028240258
        helper.getDataEx();

        double[] _a = PointTransform.mercator_decrypt(3433489.21699, 11858139.6038);
        double[] a = PointTransform.bd_decrypt(29.620028240258, 106.52232140972);
        double[] b = PointTransform.gcj_decrypt(a[0], a[1]);
    }

    public GaodoHelper() {
        // wZhudiwangxiaoqu();
    }

    public void getPointChange() {
        //106.500332,29.512254  ;106.567104,29.513158 106.557785,29.655879
        double[] dou = PointTransform.gcj_decrypt(29.655879, 106.557785);
        System.out.println(dou[1] + "," + dou[0]);

    }

    public void getDataRegion() {
        List<BuildingEx> buildingExes = getCellId();
        List<RegionRing> regionRings = getRegion();

        //去重
        Map<String, BuildingEx> map = new HashMap<>();
        for (BuildingEx b : buildingExes) {
            if (!map.containsKey(b.getId())) {
                map.put(b.getId(), b);
            }
        }
        List<BuildingEx> list = new ArrayList<>();
        list.addAll(map.values());


        list = CollUtils.sortByField(list, "type", true);

        for (BuildingEx b : list) {
            for (RegionRing r : regionRings) {
                if (GeoUtils.isPointInPolygon(r.getRings(), b.getCenter().getX(), b.getCenter().getY())) {
                    b.setCityName(r.getName());
                    break;
                }
            }
        }
        wCell(list);
    }

    public void getData() {

        List<BuildingEx> list = new ArrayList<>();
        List<BuildingEx> temp = new ArrayList<>();

        System.out.println("开始读取小区数据。。。");
        //List<Cell> cells = getCell();
        List<Cell> cells = getMapbarpoiCell();
        System.out.println("开始采集数据。。。");
        //int i = getCellId();
        int i = 0;
        System.out.println("开始采集数据" + i + "。。。");
        for (; i < cells.size(); i++) {
            Cell cell = cells.get(i);
            temp.clear();
            int pagesCount = 1;
            GaodeResult<BuildingEx> result = getGaodeData_Query(cell.getName(), pagesCount, cell.getCell_order_id());

            if (result.getStatus().equals("6")) {
                while (true)
                    try {
                        Thread.sleep(10000);
                        System.out.println(TimeUtils.dateConvertString(new Date(), "yyyy-MM-dd HH:mm:ss") + ":需要页面验证。。。。。。。");
                        result = getGaodeData_Query(cell.getName(), pagesCount, cell.getCell_order_id());
                        if (!result.getStatus().equals("6")) {
                            break;
                        }
                    } catch (InterruptedException e) {

                    }
            }

            if (result.getData().size() > 0) {
                temp.addAll(result.getData());
            }

            /*if (result.getPagecount() > 1) {
                pagesCount = result.getPagecount();
                for (int _pageCount = 2; _pageCount <= pagesCount; _pageCount++) {
                    result = getGaodeData_Query(cell.getName(), _pageCount);
                    if (result.getData().size() > 0) {
                        temp.addAll(result.getData());
                    }
                }
            }*/

            if (temp.size() == 0) {
                BuildingEx building = new BuildingEx();
                building.setIndex(cell.getCell_order_id());
                temp.add(building);
                building.setId(StringUtils.isNotEmpty(cell.getId()) ? cell.getId() : cell.getTag() + "");
                building.setName(cell.getName());
                building.setCenterX(cell.getLongitude());
                building.setCenterY(cell.getLatitude());
                building.setDistrict(cell.getCityName());
                building.setType(2);
                building.setExtent(new Extent(building.getCenter().getX() - 0.0005, building.getCenter().getX() + 0.0005, building.getCenter().getY() - 0.0005, building.getCenter().getY() + 0.0005));
                building.getRing().add(new GeoPoint(building.getExtent().getxMin(), building.getExtent().getyMin()));
                building.getRing().add(new GeoPoint(building.getExtent().getxMin(), building.getExtent().getyMax()));
                building.getRing().add(new GeoPoint(building.getExtent().getxMax(), building.getExtent().getyMax()));
                building.getRing().add(new GeoPoint(building.getExtent().getxMax(), building.getExtent().getyMin()));
                building.getRing().add(new GeoPoint(building.getExtent().getxMin(), building.getExtent().getyMin()));

            }
            list.addAll(temp);

            if ((i + 1) % 10 == 0) {
                System.out.println("Count is " + (i + 1) + ". Finished is " + MathUtils.round((i * 1.0 / cells.size()) * 100, 2) + "%");
                wCell(list);
                list.clear();
            }
        }
        if (list.size() > 0) {
            wCell(list);
            list.clear();

        }
        System.out.println("Finished is 100%");

        /*System.out.println("开始去除重复数据。。。");
        Map<String, BuildingEx> disMap = new HashMap<>();
        List<BuildingEx> disList = new ArrayList<>();
        for (BuildingEx b : list) {
            if (!disMap.containsKey(b.getId())) {
                disMap.put(b.getId(), b);
                disList.add(b);
            }
        }
        System.out.println("开始对数据排序");
        disList = CollUtils.sortByField(disList, "type", true);
        System.out.println("开始写文件");
        wCell(disList);
        System.out.println("生成文件完成!");*/

    }

    private List<BuildingEx> getGaodeData(String poiName) {
        List<BuildingEx> list = new ArrayList<>();
        BuildingEx building = null;
        try {
            String path = "&city=500000&words=" + URLEncoder.encode(poiName, "utf-8");
            String jsonStr = HttpRequest.sendGet(queryWord, path);
            JSONObject httpJson = new JSONObject(jsonStr);
            String status = httpJson.getString("status");
            if (status.equals("1")) {

                JSONObject dataJson = httpJson.getJSONObject("data");
                JSONArray tip_list = dataJson.getJSONArray("tip_list");
                for (int j = 0; j < tip_list.length(); j++) {
                    building = new BuildingEx();
                    JSONObject tip = tip_list.getJSONObject(j).getJSONObject("tip");
                    String adcode = tip.getString("adcode");
                    String poiid = tip.getString("poiid");
                    String name = tip.getString("name");
                    //取边界数据
                    path = "&id=" + poiid + "&city=" + adcode + "&keywords=" + URLEncoder.encode(name, "utf-8");
                    String cellStr = HttpRequest.sendGet(queryCell, path);
                    if (StringUtils.isEmpty(cellStr)) {
                        continue;
                    }
                    JSONObject cellJson = new JSONObject(cellStr);
                    if (cellJson == null || !cellJson.getString("status").equals("1")) {
                        continue;
                    }

                    JSONArray cellData = cellJson.getJSONArray("data");
                    for (int k = 0; k < cellData.length(); k++) {
                        JSONObject cellDataItem = cellData.getJSONObject(k);
                        String type = cellDataItem.getString("type");
                        if (type.equals("polygon")) {//读取边界数据
                            JSONArray cellDataItemList = cellDataItem.getJSONArray("list");
                            for (int m = 0; m < cellDataItemList.length(); m++) {
                                JSONObject boundJson = cellDataItemList.getJSONObject(m);
                                if (boundJson.getString("id").equals(poiid)) {
                                    JSONArray boundArr = boundJson.getJSONArray("bound");
                                    for (int n = 0; n < boundArr.length(); n++) {
                                        String[] pStr = boundArr.getString(n).split(",");
                                        double[] p = PointTransform.gcj_decrypt(Double.parseDouble(pStr[1]), Double.parseDouble(pStr[0]));
                                        building.getRing().add(new GeoPoint(p[1], p[0]));
                                    }
                                    Extent extent = GeoUtils.getExtent(building.getRing());
                                    building.setExtent(extent);

                                    building.setId(poiid);
                                    building.setName(name);
                                    building.setAdcode(adcode);
                                    if (tip.isNull("district") == false)
                                        building.setDistrict(tip.getString("district"));
                                    if (tip.isNull("address") == false)
                                        building.setAddress(tip.getString("address"));
                                    if (tip.isNull("x") == false && tip.isNull("y") == false) {
                                        double[] center = PointTransform.gcj_decrypt(tip.getDouble("y"), tip.getDouble("x"));
                                        building.setCenterX(center[1]);
                                        building.setCenterY(center[0]);
                                    }
                                }
                            }
                        }

                    }
                    if (building.getRing().size() > 0) {
                        building.setTag(1);
                        list.add(building);
                    }

                }

                //如果没有取到数据
                if (list.size() == 0 && tip_list.length() > 0) {
                    JSONObject tip = tip_list.getJSONObject(0).getJSONObject("tip");
                    if (tip.getString("name").equals(poiName)) {
                        building = new BuildingEx();
                        list.add(building);

                        building.setTag(0);
                        building.setId(tip.getString("poiid"));
                        building.setName(tip.getString("name"));
                        building.setAdcode(tip.getString("adcode"));
                        if (tip.isNull("district") == false)
                            building.setDistrict(tip.getString("district"));
                        if (tip.isNull("address") == false)
                            building.setAddress(tip.getString("address"));
                        if (tip.isNull("x") == false && tip.isNull("y") == false) {
                            double[] center = PointTransform.gcj_decrypt(tip.getDouble("y"), tip.getDouble("x"));
                            building.setCenterX(center[1]);
                            building.setCenterY(center[0]);
                            building.setExtent(new Extent(building.getCenter().getX() - 0.0005, building.getCenter().getX() + 0.0005, building.getCenter().getY() - 0.0005, building.getCenter().getY() + 0.0005));
                            building.getRing().add(new GeoPoint(building.getExtent().getxMin(), building.getExtent().getyMin()));
                            building.getRing().add(new GeoPoint(building.getExtent().getxMin(), building.getExtent().getyMax()));
                            building.getRing().add(new GeoPoint(building.getExtent().getxMax(), building.getExtent().getyMax()));
                            building.getRing().add(new GeoPoint(building.getExtent().getxMax(), building.getExtent().getyMin()));
                            building.getRing().add(new GeoPoint(building.getExtent().getxMin(), building.getExtent().getyMin()));
                        }
                    }
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return list;
    }

    private GaodeResult getGaodeData_Query(String poiName, int pageindex, int index) {
        Map<String, BuildingEx> map = new HashMap<>();
        BuildingEx building = null;
        GaodeResult<BuildingEx> result = new GaodeResult<>();
        result.setPageindex(pageindex);
        try {
            int pagecount = 0;
            String path = query + "&pagenum=" + pageindex + "&keywords=" + URLEncoder.encode(poiName, "utf-8");
            String jsonStr = HttpRequest.sendGet(path, null);
            JSONObject httpJson = new JSONObject(jsonStr);
            String status = httpJson.getString("status");
            result.setStatus(status);
            if (status.equals("1")) {
                if (httpJson.isNull("pagecount") == false) {
                    pagecount = httpJson.getInt("pagecount");
                    result.setPagecount(pagecount);
                }

                JSONArray cellData = httpJson.getJSONArray("data");
                for (int k = 0; k < cellData.length(); k++) {
                    JSONObject cellDataItem = cellData.getJSONObject(k);
                    String type = cellDataItem.getString("type");

                    if (type.equals("marker")) {//POI信息
                        JSONArray cellDataItemList = cellDataItem.getJSONArray("list");
                        for (int m = 0; m < cellDataItemList.length(); m++) {
                            JSONObject tip = cellDataItemList.getJSONObject(m);
                            String id = tip.getString("id");
                            if (map.containsKey(id)) {
                                continue;
                            }
                            building = new BuildingEx();
                            map.put(id, building);
                            building.setId(id);
                            building.setName(tip.getString("name"));
                            building.setAdcode(tip.getString("adcode"));
                            if (tip.isNull("longitude") == false && tip.isNull("latitude") == false) {
                                double[] center = PointTransform.gcj_decrypt(tip.getDouble("latitude"), tip.getDouble("longitude"));
                                building.setCenterX(center[1]);
                                building.setCenterY(center[0]);
                            }
                            if (tip.isNull("address") == false)
                                building.setAddress(tip.getString("address"));
                        }
                    }
                    if (type.equals("polygon")) {//读取边界数据
                        JSONArray cellDataItemList = cellDataItem.getJSONArray("list");
                        for (int m = 0; m < cellDataItemList.length(); m++) {
                            JSONObject tip = cellDataItemList.getJSONObject(m);
                            String id = tip.getString("id");
                            if (map.containsKey(id)) {
                                BuildingEx item = map.get(id);
                                JSONArray boundArr = tip.getJSONArray("bound");
                                for (int n = 0; n < boundArr.length(); n++) {
                                    String[] pStr = boundArr.getString(n).split(",");
                                    double[] p = PointTransform.gcj_decrypt(Double.parseDouble(pStr[1]), Double.parseDouble(pStr[0]));
                                    item.getRing().add(new GeoPoint(p[1], p[0]));
                                }
                                Extent extent = GeoUtils.getExtent(item.getRing());
                                item.setExtent(extent);
                                item.setType(0);
                                item.setIndex(index);
                                result.getData().add(item);
                            }
                        }
                    }
                }

                //如果没有取到数据
                if (result.getData().size() == 0 && map.size() > 0) {
                    for (Map.Entry<String, BuildingEx> MapString : map.entrySet()) {
                        BuildingEx value = MapString.getValue();
                        if (value.getName().equals(poiName)) {
                            result.getData().add(value);
                            value.setIndex(index);
                            value.setType(1);
                            value.setExtent(new Extent(value.getCenter().getX() - 0.0005, value.getCenter().getX() + 0.0005, value.getCenter().getY() - 0.0005, value.getCenter().getY() + 0.0005));
                            value.getRing().add(new GeoPoint(value.getExtent().getxMin(), value.getExtent().getyMin()));
                            value.getRing().add(new GeoPoint(value.getExtent().getxMin(), value.getExtent().getyMax()));
                            value.getRing().add(new GeoPoint(value.getExtent().getxMax(), value.getExtent().getyMax()));
                            value.getRing().add(new GeoPoint(value.getExtent().getxMax(), value.getExtent().getyMin()));
                            value.getRing().add(new GeoPoint(value.getExtent().getxMin(), value.getExtent().getyMin()));

                        }
                    }

                }
            }
            //Thread.sleep(1000);

        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }

    /**
     * 加载高德小区
     *
     * @return
     */
    private List<Cell> getCell() {
        List<Cell> list = new ArrayList<>();
        String filePath = basePath + "config/communities.txt";
        InputStreamReader stream = null;
        BufferedReader reader = null;
        Cell cell = null;
        int count = 0;
        String[] datas;
        try {
            stream = new InputStreamReader(new FileInputStream(filePath), "UTF-8");
            reader = new BufferedReader(stream);
            String line = null;

            while ((line = reader.readLine()) != null) {
                count++;
                if (StringUtils.isEmpty(line) || count == 1) {
                    continue;
                }
                // 文本中第一个字符为特殊字符
                if ((int) line.charAt(0) == 65279) {
                    line = line.substring(1);
                }

                datas = StringUtils.splitPreserveAllTokens(line, ",");
                cell = new Cell();
                cell.setCell_order_id(count - 1);
                cell.setTag(datas[0]);
                cell.setId(datas[1]);
                cell.setName(datas[2]);
                cell.setLatitude(Double.parseDouble(datas[6]));
                cell.setLongitude(Double.parseDouble(datas[7]));
                cell.setCityName(datas[9]);
                cell.setCityId(datas[11]);
                list.add(cell);
            }

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        } finally {
            CoreUtils.close(reader, stream);
        }

        return list;
    }

    private List<BuildingEx> getCellId() {
        int count = 0;

        List<BuildingEx> list = new ArrayList<>();
        String filePath = basePath + "config/gaodecommunities.txt";
        InputStreamReader stream = null;
        BufferedReader reader = null;
        Cell cell = null;
        String[] datas;
        String line = null;
        try {
            stream = new InputStreamReader(new FileInputStream(filePath), "UTF-8");
            reader = new BufferedReader(stream);
            String _line;
            while ((_line = reader.readLine()) != null) {
                line = _line;
                if (count > 0) {
                    String[] arr = StringUtils.splitPreserveAllTokens(line, "|");
                    BuildingEx building = new BuildingEx();
                    list.add(building);
                    building.setType(Integer.parseInt(arr[0]));
                    building.setIndex(Integer.parseInt(arr[1]));
                    building.setId(arr[2]);
                    building.setName(arr[3]);
                    building.setAdcode(arr[4]);
                    building.setAddress(arr[5]);
                    if (building.getType() == 2) {
                        building.setExtent(new Extent(Double.parseDouble(arr[9]), Double.parseDouble(arr[7]), Double.parseDouble(arr[8]), Double.parseDouble(arr[6])));
                        building.setCenterX(Double.parseDouble(arr[11]));
                        building.setCenterY(Double.parseDouble(arr[10]));
                        building.getRing().add(new GeoPoint(building.getExtent().getxMin(), building.getExtent().getyMin()));
                        building.getRing().add(new GeoPoint(building.getExtent().getxMin(), building.getExtent().getyMax()));
                        building.getRing().add(new GeoPoint(building.getExtent().getxMax(), building.getExtent().getyMax()));
                        building.getRing().add(new GeoPoint(building.getExtent().getxMax(), building.getExtent().getyMin()));
                        building.getRing().add(new GeoPoint(building.getExtent().getxMin(), building.getExtent().getyMin()));
                        building.setStrRing(StringUtils.join(building.getRing().toArray(), ","));

                    } else {
                        building.setExtent(new Extent(Double.parseDouble(arr[8]), Double.parseDouble(arr[6]), Double.parseDouble(arr[9]), Double.parseDouble(arr[7])));
                        building.setCenterX(Double.parseDouble(arr[10]));
                        building.setCenterY(Double.parseDouble(arr[11]));
                        building.setStrRing(arr[12]);
                    }
                    //String[] arr_ring = StringUtils.splitPreserveAllTokens(arr[12], "|");
                }
                count++;
            }

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        } finally {
            CoreUtils.close(reader, stream);
        }
        count++;
        /*if (StringUtils.isNotEmpty(line) && line != null) {
            try {
                count = Integer.parseInt(StringUtils.splitPreserveAllTokens(line, "|")[1]);
            } catch (Exception e) {
            }
        }*/
        return list;
    }

    private List<RegionRing> getRegion() {
        int count = 0;
        List<RegionRing> list = new ArrayList<>();
        String filePath = basePath + "config/region_chongqing.txt";
        InputStreamReader stream = null;
        BufferedReader reader = null;
        RegionRing regionRing = null;
        try {
            stream = new InputStreamReader(new FileInputStream(filePath), "UTF-8");
            reader = new BufferedReader(stream);
            String _line;
            while ((_line = reader.readLine()) != null) {
                String[] arr = StringUtils.splitPreserveAllTokens(_line, ",");
                if (count == 0) {
                    regionRing = new RegionRing();
                    regionRing.setName(arr[0]);
                    list.add(regionRing);
                    count++;
                } else if (count == 1) {
                    count++;
                } else if (count == 2) {
                    for (int i = 0; i < arr.length; i = i + 2) {
                        if (i < arr.length && i + 1 < arr.length && StringUtils.isNotBlank(arr[i])) {
                            if (StringUtils.isBlank(arr[i]) || StringUtils.isBlank(arr[i + 1])) {
                                int a = i;
                            }
                            regionRing.getRings().add(new GeoPoint(Double.parseDouble(arr[i]), Double.parseDouble(arr[i + 1])));
                        }
                    }
                    count = 0;
                }
            }

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        } finally {
            CoreUtils.close(reader, stream);
        }
        return list;
    }

    /**
     * 生成文件
     *
     * @param cells
     */
    private void wCell(List<BuildingEx> cells) {
        //开始写入文件
        int f = 0;
        String path = basePath + "config/gaode_comm.txt";
        File file = new File(path);
        boolean isTitle = false;
        if (!file.exists()) {
            isTitle = true;
        }
        FileOutputStream out = null;
        OutputStreamWriter osw = null;
        BufferedWriter bw = null;
        try {
            out = new FileOutputStream(file, true);
            osw = new OutputStreamWriter(out, "UTF-8");
            bw = new BufferedWriter(osw);
            if (isTitle) {
                //标题
                bw.append("type|index|id|name|cityName|adcode|address|xmax|ymax|xmin|ymin|centerx|centery|ring\n");
                isTitle = false;
            }
            for (f = 0; f < cells.size(); f++) {
                StringBuffer sb = new StringBuffer();
                BuildingEx b = cells.get(f);
                if (b.getRing().size() == 0) {
                    //continue;
                }

                sb.append(b.getType() + "|" + b.getIndex() + "|" + b.getId() + "|" + b.getName() + "|" + b.getCityName() + "|" + b.getAdcode() + "|" + b.getAddress());
                sb.append("|" + b.getExtent().getxMax() + "|" + b.getExtent().getyMax() + "|" + b.getExtent().getxMin() + "|" + b.getExtent().getyMin());

                GeoPoint center = b.getCenter();
                if (center == null) {
                    center = GeoUtils.getGravityCenter(b.getRing());
                }
                sb.append("|" + center.getX() + "|" + center.getY());
                //sb.append("|" + StringUtils.join(b.getRing().toArray(), ","));
                sb.append("|" + b.getStrRing());
                sb.append("\n");
                bw.write(sb.toString());
            }
            bw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void wGaode_Comm(List<BuildingEx> cells) {
        //开始写入文件
        int f = 0;
        String path = basePath + "config/gaode_comm.txt";
        File file = new File(path);
        boolean isTitle = false;
        if (!file.exists()) {
            file.delete();
        }

        FileOutputStream out = null;
        OutputStreamWriter osw = null;
        BufferedWriter bw = null;
        try {
            out = new FileOutputStream(file, false);
            osw = new OutputStreamWriter(out, "UTF-8");
            bw = new BufferedWriter(osw);
            if (isTitle) {
                //标题
                bw.append("type|index|id|name|cityName|adcode|address|xmax|ymax|xmin|ymin|centerx|centery|ring\n");
                isTitle = false;
            }
            for (f = 0; f < cells.size(); f++) {
                StringBuffer sb = new StringBuffer();
                BuildingEx b = cells.get(f);
                if (b.getRing().size() == 0) {
                    //continue;
                }

                sb.append(b.getType() + "|" + b.getIndex() + "|" + b.getId() + "|" + b.getName() + "|" + b.getCityName() + "|" + b.getAdcode() + "|" + b.getAddress());
                sb.append("|" + b.getExtent().getxMax() + "|" + b.getExtent().getyMax() + "|" + b.getExtent().getxMin() + "|" + b.getExtent().getyMin());

                GeoPoint center = b.getCenter();
                if (center == null) {
                    center = GeoUtils.getGravityCenter(b.getRing());
                }
                sb.append("|" + center.getX() + "|" + center.getY());
                //sb.append("|" + StringUtils.join(b.getRing().toArray(), ","));
                sb.append("|" + b.getStrRing());
                sb.append("\n");
                bw.write(sb.toString());
            }
            bw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public List<BuildingEx> wZhudiwangxiaoqu() {
        int count = 0;
        List<BuildingEx> list = new ArrayList<>();
        String filePath = basePath + "config/zhudiwangxiaoqu.txt";
        InputStreamReader stream = null;
        BufferedReader reader = null;
        String line = null;
        Map<String, BuildingEx> map = new HashMap<>();

        try {
            stream = new InputStreamReader(new FileInputStream(filePath), "UTF-8");
            reader = new BufferedReader(stream);
            while ((line = reader.readLine()) != null) {
                if (count > 0) {
                    String[] arr = StringUtils.splitPreserveAllTokens(line, ",");
                    if (StringUtils.isEmpty(arr[4]) || StringUtils.isEmpty(arr[7]) || StringUtils.isEmpty(arr[6])) {
                        continue;
                    }
                    double x = Double.parseDouble(arr[7]);
                    double y = Double.parseDouble(arr[6]);
                    if (y > x) {
                        double temp = x;
                        x = y;
                        y = temp;
                    }
                    double[] dou = PointTransform.gcj_decrypt(y, x);
                    String key = arr[1] + arr[2] + arr[3] + arr[4];
                    if (map.containsKey(key)) {
                        BuildingEx building = map.get(key);
                        building.getRing().add(new GeoPoint(dou[1], dou[0]));
                    } else {
                        BuildingEx building = new BuildingEx();
                        map.put(key, building);
                        building.setId(CommonUtils.oid(key) + "");
                        building.setName(arr[4].replace("，", ","));
                        building.setCityName(arr[1]);
                        building.setAddress((arr[1] + arr[2] + arr[3] + arr[4]).replace("，", ","));
                        building.getRing().add(new GeoPoint(dou[1], dou[0]));
                    }
                }
                count++;
            }

        } catch (Exception e) {
            //logger.error(e.getMessage(), e);
            System.out.println(e.toString());
        } finally {
            CoreUtils.close(reader, stream);
        }
        list.addAll(map.values());


        //写入文件
        String path = basePath + "config/zhudiwang_comm.txt";
        File file = new File(path);
        boolean isTitle = false;
        if (!file.exists()) {
            isTitle = true;
        }

        FileOutputStream out = null;
        OutputStreamWriter osw = null;
        BufferedWriter bw = null;
        try {
            out = new FileOutputStream(file, true);
            osw = new OutputStreamWriter(out, "UTF-8");
            bw = new BufferedWriter(osw);
            //标题
            bw.append("id|name|cityName|address|lon|lat|ring\n");
            for (BuildingEx b : list) {
                StringBuffer sb = new StringBuffer();

                sb.append(b.getId() + "|" + b.getName() + "|" + b.getCityName() + "|" + b.getAddress());

                GeoPoint center = GeoUtils.getGravityCenter(b.getRing());
                if (Double.isNaN(center.getX()) || Double.isNaN(center.getY())) {
                    sb.append("|" + b.getRing().get(0).getX() + "|" + b.getRing().get(0).getY());
                } else {
                    sb.append("|" + center.getX() + "|" + center.getY());
                }

                sb.append("|" + StringUtils.join(b.getRing().toArray(), ","));
                sb.append("\n");
                bw.write(sb.toString());
            }
            bw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return list;
    }

    public List<BuildingEx> readGaodeComm() {
        int count = 0;
        List<BuildingEx> list = new ArrayList<>();
        String filePath = basePath + "config/gaode_comm.txt";
        InputStreamReader stream = null;
        BufferedReader reader = null;
        Cell cell = null;
        String line = null;
        try {
            stream = new InputStreamReader(new FileInputStream(filePath), "UTF-8");
            reader = new BufferedReader(stream);
            String _line;
            while ((_line = reader.readLine()) != null) {
                line = _line;
                if (count > 0) {
                    String[] arr = StringUtils.splitPreserveAllTokens(line, "|");
                    BuildingEx building = new BuildingEx();
                    list.add(building);
                    building.setType(Integer.parseInt(arr[0]));
                    building.setIndex(Integer.parseInt(arr[1]));
                    building.setId(arr[2]);
                    building.setName(arr[3]);
                    building.setCityName(arr[4]);
                    building.setAdcode(arr[5]);
                    building.setAddress(arr[6]);
                    building.setExtent(new Extent(Double.parseDouble(arr[9]), Double.parseDouble(arr[7]), Double.parseDouble(arr[10]), Double.parseDouble(arr[8])));
                    building.setCenterX(Double.parseDouble(arr[11]));
                    building.setCenterY(Double.parseDouble(arr[12]));
                    building.setStrRing(arr[13]);
                    String[] rings = StringUtils.splitPreserveAllTokens(arr[13], ",");
                    for (int i = 0; i < rings.length; i = i + 2) {
                        if (i + 1 < rings.length)
                            building.getRing().add(new GeoPoint(Double.parseDouble(rings[i]), Double.parseDouble(rings[i + 1])));
                    }
                    //double area = GeoUtils.getArea(building.getRing());
                    GeoPoint p = GeoUtils.lonLatToMercator(building.getExtent().getxMax() - building.getExtent().getxMin(), building.getExtent().getyMax() - building.getExtent().getyMin());
                    double a = p.getX() * p.getY();
                    building.setArea(a);
                }
                count++;
            }

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        } finally {
            CoreUtils.close(reader, stream);
        }
        return list;
    }

    public List<BuildingEx> readZhudiwangxiaoqu() {
        int count = 0;
        List<BuildingEx> list = new ArrayList<>();
        String filePath = basePath + "config/zhudiwang_comm.txt";
        InputStreamReader stream = null;
        BufferedReader reader = null;
        String line = null;

        try {
            stream = new InputStreamReader(new FileInputStream(filePath), "UTF-8");
            reader = new BufferedReader(stream);
            while ((line = reader.readLine()) != null) {
                if (count > 0) {
                    String[] arr = StringUtils.splitPreserveAllTokens(line, "|");
                    BuildingEx buildingEx = new BuildingEx();
                    buildingEx.setId(arr[0]);
                    buildingEx.setName(arr[1]);
                    buildingEx.setCityName(arr[2]);
                    buildingEx.setAddress(arr[3]);
                    buildingEx.setCenter(new GeoPoint(Double.parseDouble(arr[4]), Double.parseDouble(arr[5])));
                    String[] rings = StringUtils.splitPreserveAllTokens(arr[6], ",");

                    for (int i = 0; i < rings.length; i = i + 2) {
                        buildingEx.getRing().add(new GeoPoint(Double.parseDouble(rings[i]), Double.parseDouble(rings[i + 1])));
                    }
                    list.add(buildingEx);
                }
                count++;
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            CoreUtils.close(reader, stream);
        }
        return list;
    }

    /**
     * 获取建筑物
     *
     * @return
     */
    public List<Building> getBuildings() {
        List<Building> list = new ArrayList<>();
        String filePath = basePath + "config/ads_loc_building.txt";
        InputStreamReader stream = null;
        BufferedReader reader = null;
        Building building = null;
        int count = 0;
        try {
            stream = new InputStreamReader(new FileInputStream(filePath), "UTF-8");
            reader = new BufferedReader(stream);
            String line = null;
            List<GeoPoint> rings = null;

            while ((line = reader.readLine()) != null) {
                count++;

                /*if (2000000 > count) {
                    continue;
                }*/

                if (StringUtils.isEmpty(line)) {
                    break;
                }

                // 文本中第一个字符为特殊字符
                if ((int) line.charAt(0) == 65279) {
                    line = line.substring(1);
                }

                String[] datas = StringUtils.splitPreserveAllTokens(line, "|");
                building = new Building();
                building.setId(datas[0]);

                building.setXmax(Double.parseDouble(datas[1]));
                building.setYmax(Double.parseDouble(datas[2]));
                building.setXmix(Double.parseDouble(datas[3]));
                building.setYmix(Double.parseDouble(datas[4]));
                building.setCenterX(Double.parseDouble(datas[5]));
                building.setCenterY(Double.parseDouble(datas[6]));
                building.setRing(datas[7]);

                list.add(building);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            CoreUtils.close(reader, stream);
        }
        return list;
    }

    public void jiCell() {
        List<BuildingEx> yes = new ArrayList<>();//关联上高德边界的驻地网小区
        List<BuildingEx> no = new ArrayList<>();//没有关联上高德边界的驻地网小区
        List<BuildingEx> gaode_comm = new ArrayList<>();//需要生成边界的小区

        List<KeyValue> rel_id_list = new ArrayList<>();
        boolean flage = false;

        System.out.println("加载驻地网小区");
        List<BuildingEx> zdw_cells = readZhudiwangxiaoqu();

        System.out.println("加载高德数据");
        List<BuildingEx> gd_cells = readGaodeComm();

        //按面积排序
        //gd_cells = CollUtils.sortByField(gd_cells, "area", false);

        System.out.println("开始计算驻地网小区关联高德小区");
        List<BuildingEx> _cells_0 = new ArrayList<>();
        List<BuildingEx> _cells_12 = new ArrayList<>();
        for (BuildingEx b : gd_cells) {
            if (b.getType() == 0) {
                _cells_0.add(b);
            } else {
                _cells_12.add(b);
            }
        }
        gaode_comm.addAll(_cells_0);//将所有高德上采集到的有边界的数据添加到待打印的列表中

        int flag = 0;
        boolean iscontinue = false;
        for (BuildingEx b : zdw_cells) {//将驻地网小区进行关联
            flage = false;
            iscontinue = false;
            //先用中心点去关联  要是管理部上 再用边界数据去关联
            for (BuildingEx c : _cells_0) {
                if (c.getExtent().contain(b.getCenter().getX(), b.getCenter().getY())) {
                    if (GeoUtils.isPointInPolygon(c.getRing(), b.getCenter().getX(), b.getCenter().getY())) {
                        yes.add(b);
                        flage = true;
                        iscontinue = true;
                        rel_id_list.add(new KeyValue(b.getId(), c.getId()));
                        break;
                    }
                }
            }
            if (iscontinue) {
                continue;
            }

            //如果关联不到  再用具体的楼号所在的经纬度进行管理
            for (GeoPoint point : b.getRing()) {
                for (BuildingEx c : _cells_0) {
                    if (c.getExtent().contain(point.getX(), point.getY())) {
                        if (GeoUtils.isPointInPolygon(c.getRing(), point.getX(), point.getY())) {
                            yes.add(b);
                            flage = true;
                            rel_id_list.add(new KeyValue(b.getId(), c.getId()));
                            break;
                        }
                    }
                }
                if (flage) {
                    break;
                }
            }
            if (flage == false) {
                no.add(b);
            }
            flag++;
        }

        System.out.println("计算完成。其中关联成功数为：" + yes.size() + ";未关联成功数为：" + no.size() + ",未关联的小区需要与建筑物进行关联");

        //测试
        System.out.println("开始加载建筑物数据");
        List<Building> buildings = getBuildings();
        System.out.println("建筑物数据加载完成，初始化数据");
        BuildingUtils utils = new BuildingUtils();
        utils.setBuilds(buildings);
        System.out.println("开始算法运算");

        //上一步没有关联到的驻地网小区，与建筑我进行关联，如果关联到了，就添加到边界集合中
        //List<BuildingEx> yes_temp = new ArrayList<>();
        List<BuildingEx> no_temp = new ArrayList<>();
        List<Building> ring_temp = new ArrayList<>();
        DelaunayNet delaunayNet = null;
        flag = 0;
        for (BuildingEx b : no) {//开始计算上一部没有关联到的小区
            flag++;
            ring_temp.clear();
            for (GeoPoint point : b.getRing()) {
                Building building = utils.check(point.getX(), point.getY());
                if (building != null) {
                    ring_temp.add(building);
                }
            }
            if (ring_temp.size() == 1) {
                yes.add(b);

                BuildingEx buildingEx = new BuildingEx();
                buildingEx.setType(3);
                buildingEx.setId(CommonUtils.uuid());
                buildingEx.setName(b.getName());
                buildingEx.setCityName(b.getCityName());
                buildingEx.setAddress(b.getAddress());
                buildingEx.setExtent(ring_temp.get(0).getExtent());
                buildingEx.setCenter(buildingEx.getExtent().getCenter());
                buildingEx.setRing(ring_temp.get(0).getRing());
                gaode_comm.add(buildingEx);

                rel_id_list.add(new KeyValue(b.getId(), buildingEx.getId()));//添加关系

            } else if (ring_temp.size() >= 2) {
                yes.add(b);
                try {
                    VoronoiArg voronoiArg = getArg(ring_temp);
                    DelaunayBuilder delaunayBuilder = new DelaunayBuilder(voronoiArg.getVertexs());
                    delaunayNet = delaunayBuilder.calc(voronoiArg.isOptimize());
                    // 添加虚拟顶点
                    DelaunayVirtual virtual = new DelaunayVirtual();
                    delaunayNet = virtual.calc(delaunayNet);
                    List<Edge> edges = delaunayNet.getConvexEdges();
                    List<GeoPoint> e_temp = new ArrayList();
                    int e_count = edges.size();
                    for (int e_index = 0; e_index < e_count; e_index++) {
                        Edge edge = edges.get(e_index);
                        e_temp.add(new GeoPoint(edge.getStart().getX(), edge.getStart().getY()));
                        if (e_index == e_count - 1) {
                            e_temp.add(new GeoPoint(edge.getEnd().getX(), edge.getEnd().getY()));
                        }
                    }

                    BuildingEx buildingEx = new BuildingEx();
                    buildingEx.setType(4);
                    buildingEx.setId(CommonUtils.uuid());
                    buildingEx.setName(b.getName());
                    buildingEx.setCityName(b.getCityName());
                    buildingEx.setAddress(b.getAddress());
                    buildingEx.setExtent(GeoUtils.getExtent(e_temp));
                    buildingEx.setCenter(buildingEx.getExtent().getCenter());
                    buildingEx.setRing(e_temp);
                    gaode_comm.add(buildingEx);

                    rel_id_list.add(new KeyValue(b.getId(), buildingEx.getId()));//添加关系

                } catch (LogicalException e) {
                    e.printStackTrace();
                }


            } else {
                no_temp.add(b);
            }
            if (flag % 200 == 0) {
                System.out.println("Count is " + flag + ". Finished is " + MathUtils.round((flag * 1.0 / no.size()) * 100, 2) + "%");
            }
        }
        no.clear();
        no.addAll(no_temp);
        no_temp.clear();

        System.out.println("计算完成。其中关联成功数为：" + yes.size() + ";未关联成功数为：" + no.size());
        System.out.println("对未关联成功的驻地网小区进行二次边界计算");

        for (BuildingEx b : no) {//将驻地网小区进行关联
            flage = false;
            for (GeoPoint point : b.getRing()) {
                for (BuildingEx c : _cells_12) {
                    if (c.getExtent().contain(point.getX(), point.getY())) {
                        if (GeoUtils.isPointInPolygon(c.getRing(), point.getX(), point.getY())) {
                            yes.add(b);
                            flage = true;
                            rel_id_list.add(new KeyValue(b.getId(), c.getId()));
                            gaode_comm.add(c);
                            break;
                        }
                    }
                }
                if (flage) {
                    break;
                }
            }
            if (flage == false) {
                no_temp.add(b);
            }
        }
        no.clear();
        no.addAll(no_temp);
        no_temp.clear();
        System.out.println("计算完成。其中关联成功数为：" + yes.size() + ";未关联成功数为：" + no.size());

        if (no.size() > 0) {
            System.out.println("对未关联成功的驻地网小区进行边界处理");
            for (BuildingEx b : no) {//将驻地网小区进行关联
                BuildingEx buildingEx = new BuildingEx();
                buildingEx.setType(5);
                buildingEx.setId(CommonUtils.uuid());
                buildingEx.setName(b.getName());
                buildingEx.setCityName(b.getCityName());
                buildingEx.setAddress(b.getAddress());
                buildingEx.setXmax(b.getCenter().getX() + 0.0005);
                buildingEx.setXmix(b.getCenter().getX() - 0.0005);
                buildingEx.setYmax(b.getCenter().getY() + 0.0005);
                buildingEx.setYmix(b.getCenter().getY() - 0.0005);
                buildingEx.setCenter(buildingEx.getExtent().getCenter());
                buildingEx.getRing().add(new GeoPoint(b.getCenter().getX() + 0.0005, b.getCenter().getY() - 0.0005));
                buildingEx.getRing().add(new GeoPoint(b.getCenter().getX() + 0.0005, b.getCenter().getY() + 0.0005));
                buildingEx.getRing().add(new GeoPoint(b.getCenter().getX() - 0.0005, b.getCenter().getY() + 0.0005));
                buildingEx.getRing().add(new GeoPoint(b.getCenter().getX() - 0.0005, b.getCenter().getY() - 0.0005));
                buildingEx.getRing().add(new GeoPoint(b.getCenter().getX() + 0.0005, b.getCenter().getY() - 0.0005));
                gaode_comm.add(buildingEx);
                rel_id_list.add(new KeyValue(b.getId(), buildingEx.getId()));
            }
        }

        System.out.println("处理剩余的高德数据");
        Map<String, BuildingEx> map = new HashMap<>();
        for (BuildingEx c : gaode_comm) {
            if (!map.containsKey(c.getId())) {
                map.put(c.getId(), c);
            }
        }
        for (BuildingEx c : _cells_12) {
            if (!map.containsKey(c.getId())) {
                c.setType(6);
                map.put(c.getId(), c);
            }
        }
        gaode_comm.clear();
        gaode_comm.addAll(map.values());
        gaode_comm = CollUtils.sortByField(gaode_comm, "type", true);
        System.out.println("数据处理完成，开始输出高德数据!");
        outGaodeComm(gaode_comm);
        System.out.println("开始输出关联关系!");
        outRelId(rel_id_list);
        System.out.println("处理完成!");

        int a = 0;
    }

    /**
     * 获取泰森多边形算法基础数据
     *
     * @return
     */
    private VoronoiArg getArg(List<Building> buildings) {
        List<Vertex> vertexs = new ArrayList<Vertex>();
        for (int i = 0; i < buildings.size(); i++) {
            Building bts = buildings.get(i);
            for (GeoPoint p : bts.getRing()) {
                double lon = p.getX();
                double lat = p.getY();

                Vertex vertex = new Vertex();
                vertex.setX(lon);
                vertex.setY(lat);
                vertexs.add(vertex);
            }
        }

        VoronoiArg arg = new VoronoiArg();
        arg.setVertexs(vertexs);
        arg.setOptimize(true);
        return arg;
    }

    private void outGaodeComm(List<BuildingEx> list) {
        //开始写入文件
        int f = 0;
        String path = basePath + "config/gaode_comm_ok.txt";
        File file = new File(path);
        boolean isTitle = false;
        if (!file.exists()) {
            isTitle = true;
        }

        FileOutputStream out = null;
        OutputStreamWriter osw = null;
        BufferedWriter bw = null;
        try {
            out = new FileOutputStream(file, true);
            osw = new OutputStreamWriter(out, "UTF-8");
            bw = new BufferedWriter(osw);
            if (isTitle) {
                //标题
                bw.append("type|id|name|cityName|address|xmax|ymax|xmin|ymin|centerx|centery|ring\n");
                isTitle = false;
            }
            for (f = 0; f < list.size(); f++) {
                StringBuffer sb = new StringBuffer();
                BuildingEx b = list.get(f);
                if (b.getRing().size() == 0) {
                    //continue;
                }

                sb.append(b.getType() + "|" + b.getId() + "|" + b.getName() + "|" + b.getCityName() + "|" + b.getAddress());
                sb.append("|" + b.getExtent().getxMax() + "|" + b.getExtent().getyMax() + "|" + b.getExtent().getxMin() + "|" + b.getExtent().getyMin());

                GeoPoint center = b.getCenter();
                if (center == null) {
                    center = GeoUtils.getGravityCenter(b.getRing());
                }
                sb.append("|" + center.getX() + "|" + center.getY());
                sb.append("|" + StringUtils.join(b.getRing().toArray(), ","));
                sb.append("\n");
                bw.write(sb.toString());
            }
            bw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void outRelId(List<KeyValue> list) {
        //开始写入文件
        int f = 0;
        String path = basePath + "config/zhudiwang_rel.txt";
        File file = new File(path);
        boolean isTitle = false;
        if (!file.exists()) {
            isTitle = true;
        }

        FileOutputStream out = null;
        OutputStreamWriter osw = null;
        BufferedWriter bw = null;
        try {
            out = new FileOutputStream(file, true);
            osw = new OutputStreamWriter(out, "UTF-8");
            bw = new BufferedWriter(osw);
            if (isTitle) {
                //标题
                bw.append("zhudiwangid|gaode_commid\n");
                isTitle = false;
            }
            for (f = 0; f < list.size(); f++) {
                StringBuffer sb = new StringBuffer();
                KeyValue b = list.get(f);
                sb.append(b.getId() + "|" + b.getName());
                sb.append("\n");
                bw.write(sb.toString());
            }
            bw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private List<Cell> getMapbarpoiCell() {
        List<Cell> list = new ArrayList<>();
        String filePath = basePath + "t_mapbarpoi_info_liaoning.txt";
        InputStreamReader stream = null;
        BufferedReader reader = null;
        Cell cell = null;
        int count = 0;
        String[] datas;
        try {
            stream = new InputStreamReader(new FileInputStream(filePath), "UTF-8");
            reader = new BufferedReader(stream);
            String line = null;

            while ((line = reader.readLine()) != null) {
                count++;
                if (StringUtils.isEmpty(line) || count == 1) {
                    continue;
                }
                // 文本中第一个字符为特殊字符
                if ((int) line.charAt(0) == 65279) {
                    line = line.substring(1);
                }

                datas = StringUtils.splitPreserveAllTokens(line, ",");
                cell = new Cell();
                cell.setCell_order_id(count - 1);
                cell.setTag(datas[0]);
                cell.setId(datas[1]);
                cell.setName(datas[2]);
                cell.setCityName("沈阳市");
                list.add(cell);
            }

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        } finally {
            CoreUtils.close(reader, stream);
        }

        return list;
    }


    //第二版本
    public void getDataEx() {//

        //GaodeResult<BuildingEx> aa = getGaodeData_Query("促进路小区", 1);
        //getGaodePoiDetali("B0FFGQ4YXL");

        List<BuildingEx> list = new ArrayList<>();
        List<BuildingEx> temp = new ArrayList<>();

        System.out.println("开始读取小区数据。。。");
        List<Cell> cells = getCellEx();
        System.out.println("开始采集数据。。。");
        int i = 0;
        System.out.println("开始采集数据" + i + "。。。");
        for (i = 2120; i < cells.size(); i++) {
            Cell cell = cells.get(i);
            int pagesCount = 1;
            GaodeResult<BuildingEx> result = getGaodeData_Query(cell.getName(), pagesCount);
            if (result.getStatus().equals("6")) {
                while (true)
                    try {
                        Thread.sleep(10000);
                        System.out.println(TimeUtils.dateConvertString(new Date(), "yyyy-MM-dd HH:mm:ss") + ":需要页面验证。。。。。。。");
                        result = getGaodeData_Query(cell.getName(), pagesCount);
                        if (!result.getStatus().equals("6")) {
                            break;
                        }
                    } catch (InterruptedException e) {

                    }
            }

            list.addAll(result.getData());

            if (list.size() > 10) {
                System.out.println("Count is " + (i + 1) + ". Finished is " + MathUtils.round((i * 1.0 / cells.size()) * 100, 2) + "%");
                wCellEx(list);
                list.clear();
            }
        }

        if (list.size() > 0) {
            wCellEx(list);
            list.clear();
        }
        System.out.println("Finished is 100%");
    }

    private GaodeResult getGaodeData_Query(String poiName, int pageindex) {
        GaodeResult<BuildingEx> result = new GaodeResult<>();
        result.setPageindex(pageindex);
        List<BuildingEx> temp = new ArrayList<>();
        try {
            int pagecount = 0;
            String path = query + "&pagenum=" + pageindex + "&keywords=" + URLEncoder.encode(poiName, "utf-8");
            String jsonStr = HttpRequest.sendGet(path, null);
            JSONObject httpJson = new JSONObject(jsonStr);
            String status = httpJson.getString("status");
            result.setStatus(status);
            if (status.equals("1")) {
                if (httpJson.isNull("pagecount") == false) {
                    pagecount = httpJson.getInt("pagecount");
                    result.setPagecount(pagecount);
                }

                JSONObject datas = httpJson.getJSONObject("data");//.getJSONArray("poi_list");
                if (datas != null && datas.length() > 0 && datas.isNull("poi_list") == false) {
                    JSONArray poi_list = datas.getJSONArray("poi_list");
                    for (int i = 0; i < poi_list.length(); i++) {
                        JSONObject data = (JSONObject) poi_list.get(i);
                        String id = data.getString("id");
                        if (StringUtils.isEmpty(id)) {
                            continue;
                        }

                        BuildingEx buildingEx = getGaodePoiDetali(id);
                        buildingEx.setCityName(data.getString("cityname"));
                        if (buildingEx.getStatus().equals("6")) {
                            result.setStatus(buildingEx.getStatus());
                            return result;
                        }

                        if (buildingEx.getAdcode().equals("0") || buildingEx.getName().equals(poiName)) {
                            result.getData().add(buildingEx);
                        } else {
                            temp.add(buildingEx);
                        }
                    }
                }

                if (result.getData().size() == 0 && temp.size() > 0) {
                    result.getData().add(temp.get(0));
                }
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    private BuildingEx getGaodePoiDetali(String id) {
        BuildingEx building = new BuildingEx();

        try {
            String path = queryDetailById + id;
            String jsonStr = HttpRequest.sendGet(path, null);
            JSONObject httpJson = new JSONObject(jsonStr);
            building.setStatus(httpJson.getString("status"));

            if (httpJson.getString("status").equals("1")) {
                JSONObject data = httpJson.getJSONObject("data");
                JSONObject base = data.getJSONObject("base");
                building.setId(base.optString("poiid"));
                building.setName(base.getString("name"));
                building.setAddress(base.getString("address"));
                building.setTag(base.getString("tag"));
                double[] yx = PointTransform.gcj_decrypt(base.getDouble("y"), base.getDouble("x"));
                building.setCenter(new GeoPoint(yx[1], yx[0]));
                JSONObject spec = data.getJSONObject("spec");
                if (spec != null && spec.length() > 0 && spec.isNull("mining_shape") == false) {
                    JSONObject mining_shape = spec.getJSONObject("mining_shape");

                    //解决未知bug
                    if (!mining_shape.getString("shape").contains("|")) {
                        String[] shapes = StringUtils.splitPreserveAllTokens(mining_shape.getString("shape"), ";");
                        for (String shape : shapes) {
                            String[] P_str = StringUtils.splitPreserveAllTokens(shape, ",");
                            double[] p = PointTransform.gcj_decrypt(Double.parseDouble(P_str[1]), Double.parseDouble(P_str[0]));
                            building.getRing().add(new GeoPoint(p[1], p[0]));
                        }
                        building.setExtent(GeoUtils.getExtent(building.getRing()));
                        building.setCenter(building.getExtent().getCenter());
                        building.setAdcode("0");
                        building.setTag("0");
                    }
                }
                if (building.getRing().size() == 0) {
                    building.setExtent(new Extent(building.getCenter().getX() - 0.0005, building.getCenter().getX() + 0.0005, building.getCenter().getY() - 0.0005, building.getCenter().getY() + 0.0005));
                    building.getRing().add(new GeoPoint(building.getExtent().getxMin(), building.getExtent().getyMin()));
                    building.getRing().add(new GeoPoint(building.getExtent().getxMin(), building.getExtent().getyMax()));
                    building.getRing().add(new GeoPoint(building.getExtent().getxMax(), building.getExtent().getyMax()));
                    building.getRing().add(new GeoPoint(building.getExtent().getxMax(), building.getExtent().getyMin()));
                    building.getRing().add(new GeoPoint(building.getExtent().getxMin(), building.getExtent().getyMin()));
                    building.setAdcode("1");
                    building.setTag("1");
                }
            }

        } catch (Exception e) {
            System.out.println("ID is " + id);
            e.printStackTrace();
        }
        return building;
    }

    private List<Cell> getCellEx() {
        List<Cell> list = new ArrayList<>();
        String filePath = basePath + "t_mapbarpoi_info.txt";
        InputStreamReader stream = null;
        BufferedReader reader = null;
        Cell cell = null;
        int count = 0;
        String[] datas;
        try {
            stream = new InputStreamReader(new FileInputStream(filePath), "UTF-8");
            reader = new BufferedReader(stream);
            String line = null;

            while ((line = reader.readLine()) != null) {
                count++;
                if (StringUtils.isEmpty(line) || count == 1) {
                    continue;
                }
                // 文本中第一个字符为特殊字符
                if ((int) line.charAt(0) == 65279) {
                    line = line.substring(1);
                }

                datas = StringUtils.splitPreserveAllTokens(line, ",");
                cell = new Cell();
                cell.setCell_order_id(count - 1);
                cell.setTag(datas[1]);
                cell.setId(datas[2]);
                cell.setName(datas[3]);
                cell.setCityName(datas[0]);
                list.add(cell);
            }

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        } finally {
            CoreUtils.close(reader, stream);
        }

        return list;
    }


    private void wCellEx(List<BuildingEx> list) {
        //开始写入文件
        int f = 0;
        String path = basePath + "config/gaode_comm_liaoning_ok.txt";
        File file = new File(path);
        boolean isTitle = false;
        if (!file.exists()) {
            isTitle = true;
        }

        FileOutputStream out = null;
        OutputStreamWriter osw = null;
        BufferedWriter bw = null;
        try {
            out = new FileOutputStream(file, true);
            osw = new OutputStreamWriter(out, "UTF-8");
            bw = new BufferedWriter(osw);
            if (isTitle) {
                //标题
                bw.append("type|id|name|cityName|address|xmax|ymax|xmin|ymin|centerx|centery|ring\n");
                isTitle = false;
            }
            for (f = 0; f < list.size(); f++) {
                StringBuffer sb = new StringBuffer();
                BuildingEx b = list.get(f);
                if (b.getRing().size() == 0) {
                    //continue;
                }

                sb.append(b.getType() + "|" + b.getId() + "|" + b.getName() + "|" + b.getCityName() + "|" + b.getAddress());
                sb.append("|" + b.getExtent().getxMax() + "|" + b.getExtent().getyMax() + "|" + b.getExtent().getxMin() + "|" + b.getExtent().getyMin());

                GeoPoint center = b.getCenter();
                if (center == null) {
                    center = GeoUtils.getGravityCenter(b.getRing());
                }
                sb.append("|" + center.getX() + "|" + center.getY());
                sb.append("|" + StringUtils.join(b.getRing().toArray(), ","));
                sb.append("\n");
                bw.write(sb.toString());
            }
            bw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
